<template>
  <div class="login_container">
    <div class="login_box">
      <!-- 头像区域 -->
      <div class="avatar_box">
        <img src="../../assets/logo.png" alt="">
      </div>
      <!-- 登录表单 -->
      <!-- V-model是双向绑定； :model=v-bind:model只是将父组件中的数据传到子组件 -->
      <!-- ref：拿到实例对象 -->
      <el-form ref="loginFormRef" :model="loginForm" :rules="loginFormRules" label-width="0px" class="login_form">
        <!-- 用户名 -->
        <el-form-item prop="username">
          <el-input v-model="loginForm.username" prefix-icon="el-icon-user-solid" clearable></el-input>
        </el-form-item>
        <!-- 密码 -->
        <el-form-item prop="password">
          <el-input v-model="loginForm.password" prefix-icon="el-icon-lock" :type="passwordType">
             <i slot="suffix" class="el-icon-lock" @click="changePwdType"></i>
          </el-input>
          <!-- <img :src="show?openeye:closeeye" class="eye" alt="" @click="changePwdType()"> -->
        </el-form-item>
        <!-- 按钮 -->
        <el-form-item class="btns">
          <!-- <a href="/register" class="fl">无账号？去注册</a> -->
          <el-button type="primary" @click="loginAccount">登录</el-button>
          <el-button type="info" @click="resetLoginForm">重置</el-button>
        </el-form-item>
        <el-form-item class="clearfix" style="margin:0;">
          <a href="http://localhost:8080/#/user/register" class="fl">无账号？去注册</a>
          <a href="http://localhost:8080/#/user/modifyPwd" class="fr">忘记密码？</a>
          <!-- <el-button type="text" @click="modifyPwdDialogVisible=true" class="fr">忘记密码？</el-button> -->
          <!-- <a href="/user/modifyPwd" class="fr">忘记密码？</a> -->
        </el-form-item>
      </el-form>
    </div>

    <!-- 修改密码的对话框 -->
    <el-dialog title="修改密码" :visible.sync="modifyPwdDialogVisible" width="50%" @close="modifyPwdDialogClosed">
      <!-- 内容主体区域 -->
      <el-form :model="modifyPwdForm" :rules="modifyPwdFormRules" ref="modifyPwdFormRef" label-width="70px">
        <el-form-item label="用户名" prop="username">
          <el-input v-model="modifyPwdForm.username"></el-input>
        </el-form-item>
        <el-form-item label="新密码" prop="password">
          <el-input v-model="modifyPwdForm.password" :type="passwordType">
          </el-input>
        </el-form-item>
        <el-form-item label="确认密码" prop="passwords">
          <el-input v-model="modifyPwdForm.passwords" :type="passwordType">
          </el-input>
        </el-form-item>
        <el-form-item label="验证码" prop="code">
          <el-input v-model="modifyPwdForm.code"></el-input>
          <el-button type="success" @click="getCode">获取验证码</el-button>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="modifyPwdDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="modifyPwd">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import {
  getLoginAccount
} from '../../api/loginAccount.js'
export default {
  data () {
    // 验证用户名
    let validateUsername = (rule, value, callback) => {
      // 这是原本的在每个组件单独定义的，现在将其封装到vuex中，value是input框中的数据
      // 校验长度等以及正则匹配规则
      /* if (value === "") {
        callback(new Error("请输入用户名(邮箱)"));
      } else if (validateEmail(value)) {
        callback(new Error("用户名格式有误"));
      } else {
        callback(); //true
      } */
      /* 
      不能直接在钩子函数中：this.loginFormRules.username[0].validator=this.validateUsername 这样调用
      因为validateUsername并不是正常的方法，而是被包装过的方法，如果是vuex中的state数据才能这么操作，正确写法如下：
      */
      this.$store.dispatch('validateEmail',{rule, value, callback})
    };
    // 验证密码
    let validatePassword = (rule, value, callback) => {
      this.$store.dispatch('validatePassword',{rule, value, callback})
    };
    // 验证重复密码
    let validatePasswords = (rule, value, callback) => {
      // this.$store.dispatch('validatePasswords',{rule, value, callback})
    };
    // 验证验证码
    let validateCode = (rule, value, callback) => {
      this.$store.dispatch('validateCode',{rule, value, callback})
    };
    return {
      passwordType:'password',
      // 登录表单的数据绑定对象
      loginForm: {
        username: 'admin@qq.com',
        password: '123456admin'
      },
      // 这是表单的验证规则对象
      loginFormRules: {
        /* username: [
          { required: true, message: '请输入登录名', trigger: 'blur' },
          { min: 3, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'change' },
          { min: 3, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur' }
        ] */
        username: [{ validator: validateUsername, trigger: "blur" }],
        password: [{ validator: validatePassword, trigger: "blur" }],
      },
      // 控制修改密码对话框的显示与隐藏
      modifyPwdDialogVisible:false,
      // 添加修改密码的表单数据
      modifyPwdForm: {
        username: 'admin@qq.com',
        password: '123456admin',
        passwords: '123456admin',
        code:''
      },
      // 添加表单的验证规则对象，当鼠标失去焦点时，validator验证就会调用一次函数，并给函数传参
      modifyPwdFormRules: {
        username: [{ validator: validateUsername, trigger: "blur" }],
        password: [{ validator: validatePassword, trigger: "blur" }],
        passwords: [{ validator: validatePasswords, trigger: "blur" }],
        code: [{ validator: validateCode, trigger: "blur" }]
      }
    }
  },
  methods: {
    // 重置表单
    resetLoginForm () {
      this.$refs.loginFormRef.resetFields()
    },
    /* 1、第一次登录的时候，前端调后端的登陆接口，发送用户名和密码
      2、后端收到请求，验证用户名和密码，验证成功，就给前端返回一个token
      3、前端拿到token，将token存储到localStorage和vuex中，并跳转路由页面
      4、前端每次跳转路由，就判断 localStroage 中有无 token ，没有就跳转到登录页面，有则跳转到对应路由页面
      5、每次调后端接口，都要在 请求头中加t ok en 
      6、后端判断请求头中有无token，有token，就拿到token并验证token，验证成功就返回数据，验证失败（例如：token过期）就返回401，请求头中没有token也返回401
      7、如果前端拿到状态码为401，就清除token信息并跳转到登录页面 
    */
    changePwdType(){
      this.passwordType==="password"?this.passwordType="text":this.passwordType="password"
    },
    login () {
      var _that=this;
      this.$refs.loginFormRef.validate(async valid => {
        // 预校验，格式不正确阻止发送请求
        if (!valid) return;
        /* this.$http.post('/login').then(response=>{
          console.log(response);
        }) */
        const res = await this.$http.post('/login')
        console.log(res);
      /* loginAPI().then(res => {
        console.log(res)
      }).catch((err) => {
        console.log(err)
      });  */
        // 用户名和密码输入正确时才能登录成功，这个判断本应该在后端完成，但是由于没有真实后端，先在前端判断
        var account= res.data.data.find(item => item.username=== _that.loginForm.username && item.password===_that.loginForm.password);
        console.log(account);
        if (res.status !== 200 || typeof account === "undefined") return this.$message.error('用户名或密码错误');
        this.$message.success('登录成功')
        /*
          1.将登录成功之后的token（跨域）保存到客户端的sessionStorage中
            1.1 项目中除了登录之外的其他API接口，必须在登陆之后才能访问
            1.2 token 只应当在当前网站打开期间生效，所以将token保存在sessionStorage中
          2. 通过编程式导航跳转到网站主页，路由地址是 /home
          3. 将登录的用户信息保存在Vuex中
        */
        console.log(account);
        console.log(account.token);
        window.localStorage.setItem('token', account.token)

        // 由于vuex刷新后状态也会重置，所以先将account保存在本地，然后再登录后取出来赋给vuex
        // window.localStorage.setItem('account', account)
        // 将object对象存入localStorage中，要将其先用JSON.stringify转为字符串，在取出的时候再转换为json对象

        window.localStorage.setItem('account', JSON.stringify(account))

        // console.log(window.localStorage.getItem('account'));
        // console.log(JSON.parse(window.localStorage.getItem('account')));
        // 获取登录账户

        this.$store.dispatch("getLoginAccount",account)
        console.log("检查登录之后的vuex状态");
        
        console.log(this.$store.state.login);
        console.log(this.$store.state.account);
        
        this.$router.push('/home')
      })
    },
    loginAccount(){
      var _that=this;
      this.$refs.loginFormRef.validate(async valid => {
        if(!valid) return
        // 预校验，格式不正确阻止发送请求
        getLoginAccount().then(res => {
        console.log(res);
        // 用户名和密码输入正确时才能登录成功，这个判断本应该在后端完成，但是由于没有真实后端，先在前端判断
        var account= res.data.find(item => item.username=== _that.loginForm.username && item.password===_that.loginForm.password && item.status==="valid");
        console.log(account);
        if (res.status !== 200 || typeof account === "undefined") return this.$message.error('用户名或密码错误');
        this.$message.success('登录成功')
        /*
          1.将登录成功之后的token（跨域）保存到客户端的sessionStorage中
            1.1 项目中除了登录之外的其他API接口，必须在登陆之后才能访问
            1.2 token 只应当在当前网站打开期间生效，所以将token保存在sessionStorage中
          2. 通过编程式导航跳转到网站主页，路由地址是 /home
          3. 将登录的用户信息保存在Vuex中
        */
        console.log(account);
        console.log(account.token);
        window.localStorage.setItem('token', account.token)

        // 由于vuex刷新后状态也会重置，所以先将account保存在本地，然后再登录后取出来赋给vuex
        // window.localStorage.setItem('account', account)
        // 将object对象存入localStorage中，要将其先用JSON.stringify转为字符串，在取出的时候再转换为json对象

        window.localStorage.setItem('account', JSON.stringify(account))

        // console.log(window.localStorage.getItem('account'));
        // console.log(JSON.parse(window.localStorage.getItem('account')));
        // 获取登录账户

        this.$store.dispatch("getLoginAccount",account)
        console.log("检查登录之后的vuex状态");
        
        console.log(this.$store.state.login);
        console.log(this.$store.state.account);
        
        this.$router.push('/home')
      })
      })
    },
    // 监听添加用户对话框的关闭事件
    // 或者通过Vue的watch对象监听addDialogVisible属性，是false则重置表单
    modifyPwdDialogClosed() {
      this.$refs.modifyPwdFormRef.resetFields()
    },
    // 获取验证码
    getCode(){

    },
    // 修改密码
    modifyPwd(){
      
    }
  }
}
</script>

// scoped——Vue指令，控制组件样式生效区间（只在当前组件生效）
<style>
  .login_container{
    background-color: #2b4b6b;
    height: 100%;
  }

  .login_box{
    width: 450px;
    height: 350px;
    background-color: #fff;
    border-radius: 3px;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%);
  }

  .avatar_box {
    height: 130px;
    width: 130px;
    border: 1px solid #eee;
    border-radius: 50%;
    padding: 10px;
    box-shadow: 0 0 10px #ddd;
    position: absolute;
    left: 50%;
    transform: translate(-50%,-50%);
    background-color: #fff;
  }
  .avatar_box img {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background-color: #eee;
  }
  .login_form {
    position: absolute;
    bottom: 0;
    width: 100%;
    padding: 0 20px;
    box-sizing: border-box;
  }

  .btns {
    display: flex;
    justify-content: flex-end;
    margin-bottom:12px;
  }
  .el-input {
    width:410px;
    margin-right:20px;
  }
</style>
